package com.hnblc.blcwms.common.interaction;

import com.hnblc.blcwms.common.base.BaseObject;
import com.hnblc.blcwms.common.base.BaseResultEnums;
import lombok.ToString;

import java.text.DecimalFormat;
import java.text.MessageFormat;
import java.util.Locale;
import java.util.ResourceBundle;

/**
 * 
 * Response
 *
 * @author <A>cheng.yy@neusoft.com</A>
 *
 * @date Apr 15, 2015
 *
 * @Copyright: © 2001-2015 东软集团股份有限公司
 *
 */
@ToString
public class Response<T> extends BaseObject {

    private static final long serialVersionUID = 4538198473896780472L;

    private Locale defaultLocale = Locale.CHINA;
    private static final DecimalFormat FORMATTER = new DecimalFormat("000000");
    private static final String RESOURCE_NAME = "i18n.messages";
    private static final String MESSAGE_PREFIX = "RESP";
    private static final String ERROR_PREFIX = "ERROR";
    private static final String HEADER_DELIMITER = "-";
    @SuppressWarnings("unused")
    private static final String MESSAGE_DELIMITER = ": ";
    private static final String RESPONSE_SUCCESS_CODE = "RESP-01";
    private static final String RESPONSE_FAILED_CODE = "RESP-00";
    /**
     * 消息代码
     */
    private String code = null;
    /**
     * 消息字典代码
     */
    private String dicCode = null;
    /**
     * 错误代码
     */
    private String errorCode = null;
    /**
     * 错误种类
     */
    private String errorCategory = null;
    /**
     * 错误详细信息
     */
    private String errorMsg = null;

    /**
     * 消息数据
     */
    private T responseData = null;
    /**
     * 消息参数
     */
    private Object[] arguments;

    /**
     * 业务操作代码
     */
    private int optionCode;

    @SuppressWarnings("unused")
    private Response() {
        // unused
    }

    /**
     * 构造器
     * 
     * @param statusEnum
     */
    public Response(final BaseResultEnums statusEnum) {

        if (statusEnum.isSuccess()){
            this.code = ResponseDescription.RESPONSE_SUCCESS_1.getCode();
        }else {
            this.code = ResponseDescription.RESPONSE_FAILED_2.getCode();
            this.errorCode = FORMATTER.format(new Long(statusEnum.code()));
            this.errorCategory = statusEnum.category();
            this.errorMsg = statusEnum.getMessage();
        }
        dicCode = statusEnum.code();
    }

    /**
     * 构造器
     * 
     * @param statusEnum
     * @param responseData
     */
    public Response(final BaseResultEnums statusEnum,
            final T responseData) {

        if (statusEnum.isSuccess()){
            this.code = ResponseDescription.RESPONSE_SUCCESS_1.getCode();
        }else {
            this.code = ResponseDescription.RESPONSE_FAILED_2.getCode();
            this.errorCode = FORMATTER.format(new Long(statusEnum.code()));
            this.errorCategory = statusEnum.category();
            this.errorMsg = statusEnum.getMessage();
        }
        dicCode = statusEnum.code();
        this.responseData = responseData;
    }

    /**
     * 构造器
     *
     * @param statusEnum  返回状态
     * @param args
     */
    public Response(final BaseResultEnums statusEnum,
                    final Object... args) {
        if (statusEnum.isSuccess()){
            this.code = ResponseDescription.RESPONSE_SUCCESS_1.getCode();
        }else {
            this.code = ResponseDescription.RESPONSE_FAILED_2.getCode();
            this.errorCode = FORMATTER.format(new Long(statusEnum.code()));
            this.errorCategory = statusEnum.category();
            this.errorMsg = statusEnum.getMessage();
        }
        dicCode = statusEnum.code();
        arguments = args;
        if (args.length > 0) {
            if (args[0] instanceof Response) {
                @SuppressWarnings("unchecked")
                Response<T> message = (Response<T>) args[0];
                code = message.code;
                errorCode = message.errorCode;
                errorMsg = message.errorMsg;
                dicCode = message.dicCode;
                arguments = message.arguments;
            }
        }
    }

    /**
     * 构造器
     * 
     * @param statusEnum  返回状态
     * @param responseData 业务数据
     * @param args 消息参数
     */
    public Response(final BaseResultEnums statusEnum,
            final T responseData, final Object... args) {
        this.responseData = responseData;

        if (statusEnum.isSuccess()){
            this.code = ResponseDescription.RESPONSE_SUCCESS_1.getCode();
        }else {
            this.code = ResponseDescription.RESPONSE_FAILED_2.getCode();
            this.errorCode = FORMATTER.format(new Long(statusEnum.code()));
            this.errorCategory = statusEnum.category();
            this.errorMsg = statusEnum.getMessage();
        }
        dicCode = statusEnum.code();
        arguments = args;
        if (args.length > 0) {
            if (args[0] instanceof Response) {
                @SuppressWarnings("unchecked")
                Response<T> message = (Response<T>) args[0];
                code = message.code;
                errorCode = message.errorCode;
                errorMsg = message.errorMsg;
                dicCode = message.dicCode;
                arguments = message.arguments;
            }
        }
    }


    /**
     * 获取dicCode
     * 
     * @return dicCode
     */
    public String getDicCode() {
        return dicCode;
    }

    /**
     * 获取category
     * 
     * @return category
     */
    public final String getErrorCategory() {
        return this.errorCategory;
    }

    /**
     * 获取code
     * 
     * @return code
     */
    public String getCode() {
        return MESSAGE_PREFIX + HEADER_DELIMITER
                + code;
    }


    /**
     * 获取错误信息
     *
     * @return message
     */
    public final String getFailedMessage() {
            return errorCode==null?null:MessageFormat.format(errorMsg, arguments);
    }

    public final String getErrorCode(){
        return errorCode==null?null:ERROR_PREFIX + HEADER_DELIMITER + errorCategory + HEADER_DELIMITER
                + errorCode;
    }

    /**
     * 获取message
     * 
     * @return message
     */
    public String getMessage() {
        return getLocalizedMessage();
    }

    /**
     * 获取业务标识
     * 
     * @return optionCode
     */
    public int getOptionCode() {
        return optionCode;
    }

    /**
     * 设置业务标识
     * 
     * @param optionCode
     */
    public void setOptionCode(int optionCode) {
        this.optionCode = optionCode;
    }

    /**
     * 获取bundel
     * 
     * @param locale
     * @return locale
     */
    private ResourceBundle getBundle(final Locale locale) {
        ResourceBundle resourceBundle = ResourceBundle.getBundle(getBaseName(),
                locale);
        if (resourceBundle.getLocale().getLanguage()
                .equals(locale.getLanguage())) {
            return resourceBundle;
        }

        return ResourceBundle.getBundle(getBaseName());
    }

    /**
     * 获取baseName
     * 
     * @return baseName
     */
    private String getBaseName() {
        return RESOURCE_NAME;
    }

    /**
     * 获取LocalizedMessage
     * 
     * @return LocalizedMessage
     */
    public final String getLocalizedMessage() {
        return getLocalizedMessage(getDefaultLocale());
    }

    /**
     * 获取LocalizedMessage
     * 
     * @param locale
     * @return LocalizedMessage
     */
    public final String getLocalizedMessage(final Locale locale) {
        ResourceBundle resourceBundle = this.getBundle(locale);
        String resouceBundleLanguage = resourceBundle.getLocale().getLanguage();

        if (resouceBundleLanguage.length() == 0) {
            resouceBundleLanguage = Locale.getDefault().getLanguage();
        }

        if (!resouceBundleLanguage.equals(locale.getLanguage())) {
            return null;
        }
        String key = "";
        key += MESSAGE_PREFIX;
        key += HEADER_DELIMITER;
        key += code;
        String message;
        message = resourceBundle.getString(key);
        return message.replaceAll("\\.", "") + FILE_SEPARATOR;
    }

    /**
     * 获取defaultLocale
     * 
     * @return defaultLocale
     */
    public final Locale getDefaultLocale() {
        return this.defaultLocale;
    }

    /**
     * 获取responseData
     * 
     * @return responseData
     */
    public T getResponseData() {
        return (T) this.responseData;
    }

    /**
     * 设置responseData
     * 
     * @param responseData
     */
    public void setResponseData(T responseData) {
        this.responseData = responseData;
    }

    /**
     * 判断应答状态
     * 
     * @return
     */
    public boolean isSuccess() {
        if (RESPONSE_SUCCESS_CODE.equals(this.getCode())) {
            return true;
        } else if (RESPONSE_FAILED_CODE.equals(this.getCode())) {
            return false;
        } else {
            return true;
        }
    }

}